#ifndef CAMERA_H
#define CAMERA_H

#include "Hit/hittable.h"

class camera {
public:
	camera(double aspect_ratio = 1.0, int image_width = 100, double vfov = 90
		, point3 center = vec3(0, 0, 0), point3 lookat = vec3(0, 0, -1), vec3 vup = vec3(0, 1, 0));

	// 渲染
	void render(const hittable& world);

	inline void set_samples_per_pixel(int samples_per_pixel)
	{
        this->samples_per_pixel = samples_per_pixel;
	}

    inline void set_defocus_angle(double defocus_angle)
    {
        this->defocus_angle = defocus_angle;
    }

	inline void set_focus_dist(double focus_dist)
	{
		this->focus_dist = focus_dist;
	}

	inline void set_max_depth(int max_depth)
	{
		this->max_depth = max_depth;
	}

	inline void set_background(const color& background)
	{
		this->background = background;
	}

	inline void set_lights(hittable* lights)
	{
		this->lights = lights;
	}

private:
	// 初始化
	color ray_color(const ray& r, int depth, const hittable& world) const;
	// 返回一个在i,j附近的随机ray
	ray get_ray(int i, int j, int s_i, int s_j) const;
	// 返回一个([-.5,.5], [-.5,.5], 0)的随机向量
	vec3 sample_square() const;
	// 返回一个在defocus disk内的随机向量
	point3 defocus_disk_sample() const;
	vec3 sample_square_stratified(int s_i, int s_j) const;
	void initialize();

private:
	double _aspect_ratio;	// Ratio of image width over height
	int    _image_width;	// Rendered image width in pixel count
	int    _image_height;   // Rendered image height
    double _viewport_height;// 视口高度
    double _viewport_width;	// 视口宽度
	point3 _center;			// 相机位置
	point3 pixel00_loc;		// 左上角中心点坐标
	vec3   pixel_delta_u;	// per像素 u方向坐标变化量
	vec3   pixel_delta_v;	// per像素 v方向坐标变化量
	double _vfov;			// Vertical view angle (field of view)
	point3 _lookat;			// Point camera is looking at
	vec3   _vup;			// Camera-relative "up" direction
	vec3   u, v, w;         // Camera frame basis vectors

	double defocus_angle = 0;		// Variation angle of rays through each pixel
	double focus_dist = 10;			// Distance from camera lookfrom point to plane of perfect focus
	int    samples_per_pixel = 10;  // Count of random samples for each pixel
	int    max_depth = 10;			// Maximum number of ray bounces into scene

	vec3   defocus_disk_u;			// Defocus disk horizontal radius
	vec3   defocus_disk_v;			// Defocus disk vertical radius
	color  background;

	double pixel_samples_scale = 0;  // Color scale factor for a sum of pixel samples
	int    sqrt_spp = 0;             // Square root of number of samples per pixel
	double recip_sqrt_spp = 0;       // 1 / sqrt_spp

	hittable* lights;
};
#endif